﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Krile.Kernel;
using Krile.Kernel.Plugin;
using Krile.Kernel.Data;

namespace Wassrile.Operation.Web
{
    public static class DataMan
    {
        private static Dictionary<string, ulong> wassrStatusLookupper = new Dictionary<string, ulong>();

        private static Dictionary<string, DataClasses.WUser> userLookup = new Dictionary<string, Wassrile.Operation.DataClasses.WUser>();

        private static Dictionary<string, ChannelData> channelDicts = new Dictionary<string, ChannelData>();

        public class ChannelData
        {
            public ChannelData() : this(DateTime.Now) { }

            public ChannelData(DateTime lastUpdated) : this(lastUpdated, null) { }

            public ChannelData(DateTime lastUpdated, string name)
            {
                this.lastUpdated = lastUpdated;
                this.name = name;
            }

            public DateTime lastUpdated { get; set; }
            public string name { get; set; }
        }

        public static IEnumerable<KeyValuePair<string, string>> GetChannels()
        {
            return from d in channelDicts
                   select new KeyValuePair<string, string>(d.Key, d.Value.name);
        }

        public static IEnumerable<string> GetUsers()
        {
            return userLookup.Keys;
        }

        public static void RegistNewStatus(IEnumerable<DataClasses.WStatus> wsie, bool isnew)
        {
            List<Status> status = new List<Status>();
            foreach (var val in wsie)
            {
                if (wassrStatusLookupper.ContainsKey(val.Id))
                {
                    wassrStatusLookupper[val.Id] = val.UID;
                    if (Bridge.StatusManager.IdExists(val.UID))
                        Bridge.StatusManager.RemoveStatus(new ulong[] { val.UID });
                }
                else
                {
                    wassrStatusLookupper.Add(val.Id, val.UID);
                }
                status.Add((Status)val);
            }
            Bridge.StatusManager.RegistStatus(status, isnew);
        }

        public static void RegistUser(DataClasses.WUser usr)
        {
            if (userLookup.ContainsKey(usr.Id))
                userLookup[usr.Id] = usr;
            else
                userLookup.Add(usr.Id, usr);
        }

        public static void OverwriteUserName(string uid, string newName)
        {
            if (userLookup.ContainsKey(uid))
                userLookup[uid].Name = newName;
            else
                throw new ArgumentException("uid isn't exist in user storage.", "uid");

        }

        public static bool WidExists(string wid)
        {
            return wassrStatusLookupper.ContainsKey(wid);
        }

        public static ulong GetUIDFromWID(string wid)
        {
            if (wassrStatusLookupper.ContainsKey(wid))
                return wassrStatusLookupper[wid];
            else
                throw new ArgumentException("Wassr ID isn't existed.", "wid");
        }

        public static bool UserExists(string uid)
        {
            return userLookup.ContainsKey(uid);
        }

        public static DataClasses.WUser LookupUser(string uid)
        {
            if (userLookup.ContainsKey(uid))
                return userLookup[uid];
            else
                throw new ArgumentException("Selected user isn't existed.", "uid");
        }

        public static bool IsChannelRecvRequired(string chid, string chname, DateTime lastModified)
        {
            if (channelDicts.ContainsKey(chid))
            {
                if (channelDicts[chid].lastUpdated.CompareTo(lastModified) >= 0)
                    return false;
                else
                {
                    channelDicts[chid].lastUpdated = lastModified;
                    return true;
                }
            }
            else
            {
                channelDicts.Add(chid, new ChannelData(lastModified, chname));
                return true;
            }
        }
    }
}
